In [1]:
# Importing VGG16
from keras.applications import VGG16
In [2]:
network = VGG16(weights = 'imagenet',
include_top = False,
input_shape = (150, 150, 3))
In [3]:
network.summary()
In [4]:
import os
import numpy as np
from keras.preprocessing.image import ImageDataGenerator
In [5]:
base_dir = 'E:/1_GitHub/arcyfelix/Courses/In Progress-Deep Learning With Python by François Chollet/data/Chapter 5.2 - Using convets with small datasets'
In [6]:
train_dir = os.path.join(base_dir, 'train')
validation_dir = os.path.join(base_dir, 'validation')
test_dir = os.path.join(base_dir, 'test')
In [7]:
datagen = ImageDataGenerator(rescale = 1. / 255)
batch_size = 20
In [8]:
def extract_features(directory, sample_count):
# Initializing empty matrixes of a given shape
features = np.zeros(shape = (sample_count, 4, 4, 512))
labels = np.zeros(shape = (sample_count))
# Generator
generator = datagen.flow_from_directory(
directory,
target_size = (150, 150),
batch_size = batch_size,
class_mode = 'binary')
# Initializing index
i = 0
for inputs_batch, labels_batch in generator:
features_batch = network.predict(inputs_batch)
features[i * batch_size : (i + 1) * batch_size] = features_batch
labels[i * batch_size : (i + 1) * batch_size] = labels_batch
i += 1
if i * batch_size >= sample_count:
# Note that since generators yield data indefinitely in a loop,
# we must `break` after every image has been seen once.
break
return features, labels
In [9]:
train_features, train_labels = extract_features(train_dir, 2000)
validation_features, validation_labels = extract_features(validation_dir, 1000)
test_features, test_labels = extract_features(test_dir, 1000)
In [10]:
train_features.shape
Out[10]:
In [11]:
train_labels.shape
Out[11]:
In [12]:
# Flattening the features in order to feed them to a densely-connected classifier
train_features = np.reshape(train_features, (2000, 4 * 4 * 512))
validation_features = np.reshape(validation_features, (1000, 4 * 4 * 512))
test_features = np.reshape(test_features, (1000, 4 * 4 * 512))
In [13]:
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.optimizers import RMSprop
In [14]:
model = Sequential()
model.add(Dense(units = 256,
activation = 'relu',
input_dim = 4 * 4 * 512))
model.add(Dropout(rate = 0.5))
model.add(Dense(units = 1,
activation = 'sigmoid'))
model.compile(optimizer = RMSprop(lr = 2e-5),
loss = 'binary_crossentropy',
metrics = ['acc'])
In [15]:
history = model.fit(train_features,
train_labels,
epochs = 30,
batch_size = 20,
validation_data = (validation_features, validation_labels))
In [16]:
import matplotlib.pyplot as plt
In [17]:
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
In [18]:
epochs = range(len(acc))
In [19]:
plt.figure(figsize = (10, 6))
plt.plot(epochs,
acc,
'bo',
label = 'Training acc')
plt.plot(epochs,
val_acc,
'b',
label = 'Validation acc')
plt.title('Training and validation accuracy')
plt.legend()
plt.show()
In [20]:
plt.figure(figsize = (10, 6))
plt.plot(epochs,
loss,
'bo',
label = 'Training loss')
plt.plot(epochs,
val_loss,
'b',
label = 'Validation loss')
plt.title('Training and validation loss')
plt.legend()
plt.show()
In [21]:
from keras.layers import Flatten
In [22]:
end_to_end_model = Sequential()
end_to_end_model.add(network)
end_to_end_model.add(Flatten())
end_to_end_model.add(Dense(units = 256,
activation = 'relu'))
end_to_end_model.add(Dense(units = 1,
activation = 'sigmoid'))
In [23]:
end_to_end_model.summary()
In [24]:
print('Trainable weights before freezing the VGG base:', len(end_to_end_model.trainable_weights))
In [25]:
# Freezing VGG part of the network
network.trainable = False
In [26]:
print('Trainable weights after freezing the VGG base:', len(end_to_end_model.trainable_weights))
In [27]:
# Compiling the network
end_to_end_model.compile(loss = 'binary_crossentropy',
optimizer = RMSprop(lr = 2e-5),
metrics = ['acc'])
In [28]:
train_datagen = ImageDataGenerator(rescale = 1./255,
rotation_range = 40,
width_shift_range = 0.2,
height_shift_range = 0.2,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True,
fill_mode = 'nearest')
# The validation data should not be augmented!
test_datagen = ImageDataGenerator(rescale = 1./255)
In [29]:
train_generator = train_datagen.flow_from_directory(
# This is the target directory
train_dir,
# All images will be resized to 150x150
target_size = (150, 150),
batch_size = 20,
# Since we use binary_crossentropy loss, we need binary labels
class_mode = 'binary')
In [30]:
validation_generator = test_datagen.flow_from_directory(validation_dir,
target_size = (150, 150),
batch_size = 20,
class_mode = 'binary')
In [31]:
history = end_to_end_model.fit_generator(train_generator,
steps_per_epoch = 100,
epochs = 30,
validation_data = validation_generator,
validation_steps = 50,
verbose = 2)
In [32]:
model.save('.\saved_checkpoints\Chapter 5.3 - Using a pre-trained convnet\cats_and_dogs_small_3.h5')
In [33]:
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
In [34]:
epochs = range(len(acc))
In [35]:
plt.figure(figsize = (10, 6))
plt.plot(epochs,
acc,
'bo',
label = 'Training acc')
plt.plot(epochs,
val_acc,
'b',
label = 'Validation acc')
plt.title('Training and validation accuracy')
plt.legend()
plt.show()
In [36]:
plt.figure(figsize = (10, 6))
plt.plot(epochs,
loss,
'bo',
label = 'Training loss')
plt.plot(epochs,
val_loss,
'b',
label = 'Validation loss')
plt.title('Training and validation loss')
plt.legend()
plt.show()
In [37]:
network.summary()
In [38]:
# Fine-tuning only block5_conv1, block5_conv2 and block5_conv3
network.trainable = True
set_trainable = False
for layer in network.layers:
if layer.name == 'block5_conv1':
set_trainable = True
if set_trainable:
layer.trainable = True
else:
layer.trainable = False
In [39]:
# Compiling the network
end_to_end_model.compile(loss = 'binary_crossentropy',
optimizer = RMSprop(lr = 1e-5),
metrics = ['acc'])
In [40]:
history = end_to_end_model.fit_generator(train_generator,
steps_per_epoch = 100,
epochs = 100,
validation_data = validation_generator,
validation_steps = 50)
In [41]:
model.save('.\saved_checkpoints\Chapter 5.3 - Using a pre-trained convnet\cats_and_dogs_small_4.h5')
In [42]:
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
In [43]:
epochs = range(len(acc))
In [44]:
plt.figure(figsize = (10, 6))
plt.plot(epochs,
acc,
'bo',
label = 'Training acc')
plt.plot(epochs,
val_acc,
'b',
label = 'Validation acc')
plt.title('Training and validation accuracy')
plt.legend()
plt.show()
In [45]:
plt.figure(figsize = (10, 6))
plt.plot(epochs,
loss,
'bo',
label = 'Training loss')
plt.plot(epochs,
val_loss,
'b',
label = 'Validation loss')
plt.title('Training and validation loss')
plt.legend()
plt.show()
In [46]:
def smooth_curve(points, factor = 0.8):
smoothed_points = []
for point in points:
if smoothed_points:
previous = smoothed_points[-1]
smoothed_points.append(previous * factor + point * (1 - factor))
else:
smoothed_points.append(point)
return smoothed_points
In [47]:
plt.figure(figsize = (10, 6))
plt.plot(epochs,
smooth_curve(acc),
'bo',
label = 'Smoothed training acc')
plt.plot(epochs,
smooth_curve(val_acc),
'b',
label = 'Smoothed validation acc')
plt.title('Training and validation accuracy')
plt.legend()
plt.show()
In [48]:
plt.figure(figsize = (10, 6))
plt.plot(epochs,
smooth_curve(loss),
'bo',
label = 'Smoothed training loss')
plt.plot(epochs,
smooth_curve(val_loss),
'b',
label = 'Smoothed validation loss')
plt.title('Training and validation loss')
plt.legend()
plt.show()
In [49]:
test_generator = test_datagen.flow_from_directory(test_dir,
target_size = (150, 150),
batch_size = 20,
class_mode = 'binary')
test_loss, test_acc = end_to_end_model.evaluate_generator(test_generator,
steps = 50)
print('Test acc:', test_acc)